package repository

import (
	"github.com/lab-online/internal/user/entity"
	"github.com/lab-online/internal/user/infra/model"
	"github.com/lab-online/pkg/util"
)

// SaveUser 若不指定 `id` 则创建，否则更新
// 若传入的 `user` 有有效 `deleted_at` 字段，则更新时恢复软删除 (`deleted_at = NULL`)
func (r *Repository) SaveUser(userEntity entity.UserEntity) (entity.UserEntity, error) {
	user := model.NewUser(model.WithEntity(userEntity))

	var err error
	if user.ID != 0 {
		err = r.updateUser(user)
	} else {
		err = r.createUser(user)
	}

	if err != nil {
		return nil, r.errorHandler(err)
	}

	return user.ToEntity(), nil
}

func (r *Repository) createUser(user *model.User) error {
	return r.db.Create(user).Error
}

func (r *Repository) updateUser(user *model.User) error {
	if user.DeletedAt.Valid {
		user.DeletedAt.Valid = false
		// 恢复软删除, 更新包含零值字段
		return r.db.Unscoped().Model(user).Select("*").Updates(user).Error
	} else {
		return r.db.Updates(user).Error
	}
}

func (r *Repository) SaveManyUsers(userEntities []entity.UserEntity) ([]entity.UserEntity, error) {
	users := util.SliceMap(userEntities, func(userEntity entity.UserEntity) *model.User {
		return model.NewUser(model.WithEntity(userEntity))
	})

	var err error
	if err = r.db.Unscoped().Save(users).Error; err != nil {
		return nil, r.errorHandler(err)
	}

	return util.SliceMap(users, func(user *model.User) entity.UserEntity {
		return user.ToEntity()
	}), nil
}
